﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Management;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace BCGPSCommon
{
    public static class IPHelper
    {
        /// <summary>
        /// 将指定的 IP 地址转换为十进制 IP 地址。
        /// </summary>
        /// <param name="stringIPAddress"></param>
        /// <returns></returns>
        public static long ToInteger(string stringIPAddress)
        {
            string[] buffer = stringIPAddress.Split('.');

            for (int i = 0; i < buffer.Length; i++)
            {
                buffer[i] = int.Parse(buffer[i]) > 255 ? Convert.ToString(255).PadLeft(2, '0') : buffer[i] = Convert.ToString(int.Parse(buffer[i]), 16).PadLeft(2, '0');
            }

            return long.Parse(string.Concat(buffer), NumberStyles.HexNumber);
        }

        /// <summary>
        /// 将十进制 IP 地址转换为 <see cref="IPAddress"/> 的对象。
        /// </summary>
        /// <param name="integerIPAddress"></param>
        /// <returns></returns>
        public static IPAddress ToIPAddress(long integerIPAddress)
        {
            byte[] buffer = new byte[4];

            for (int i = 0; i < 4; i++)
            {
                buffer[3 - i] = (byte)(integerIPAddress >> 8 * i);
            }

            return new IPAddress(buffer);
        }

        /// <summary>
        /// 测试指定的 IP 地址是否在指定的子网中。
        /// </summary>
        /// <param name="ipAddress"></param>
        /// <param name="network"></param>
        /// <returns></returns>
        public static bool InSubnet(string ipAddress, string network)
        {
            long startIPAddress, endIPAddress;

            if (!network.Contains("/"))
            {
                startIPAddress = endIPAddress = ToInteger(network);
            }
            else if (network.EndsWith("/32"))
            {
                startIPAddress = endIPAddress = ToInteger(network.Substring(0, network.Length - 3));
            }
            else
            {
                try
                {
                    int index = network.IndexOf("/");

                    long networkPrefix = ToInteger(network.Substring(0, index));
                    int subnetMask = int.Parse(network.Substring(index + 1));

                    startIPAddress = networkPrefix & (uint.MaxValue << (32 - subnetMask));
                    endIPAddress = startIPAddress + (long)Math.Pow(2, 32 - subnetMask) - 1;
                }
                catch (Exception ex)
                {
                    throw new ArgumentException("提供的子网掩码不正确。", "network", ex);
                }
            }

            long currentIPAddress = ToInteger(ipAddress);

            return currentIPAddress >= startIPAddress && currentIPAddress <= endIPAddress;
        }

        /// <summary>
        /// 移除 IP 字符串中的端口号。
        /// </summary>
        /// <param name="ipAddress"></param>
        /// <returns></returns>
        public static string RemovePortNumber(string ipAddress)
        {
            if (string.IsNullOrWhiteSpace(ipAddress))
            {
                return ipAddress;
            }

            if (ipAddress.IndexOf(".") > 0)
            {
                // IPv4
                if (ipAddress.IndexOf(":") != -1)
                {
                    return ipAddress.Substring(0, ipAddress.IndexOf(":"));
                }

                return ipAddress;
            }
            else
            {
                // IPv6
                if (ipAddress.IndexOf("]:") != -1)
                {
                    return ipAddress.Substring(0, ipAddress.IndexOf("]:")).Substring(1);
                }

                return ipAddress;
            }
        }


        #region 获得本机局域网IP地址
        public static string GetIPAddress()
        {
            // 获得本机局域网IP地址  
            Console.WriteLine(Dns.GetHostName());
            IPAddress[] AddressList = null;


            foreach (var item in Dns.GetHostAddresses(Dns.GetHostName()))
            {
                if (item.AddressFamily == AddressFamily.InterNetwork)
                {
                    if (item.ToString() == "192.168.0.126")
                        AddressList = Dns.GetHostAddresses("192.168.0.126");
                    else
                        AddressList = Dns.GetHostAddresses("172.17.103.36"); 

                    break;
                }
            }
            if (AddressList.Length < 1)
            {
                return "";
            }
            string ip = string.Empty;
            foreach (IPAddress item in AddressList)
            {
                Console.WriteLine(item.ToString() + ":\t" + item.AddressFamily);
                Console.WriteLine(item.ToString() + ":\t" + item.IsIPv4MappedToIPv6);
                Console.WriteLine(item.ToString() + ":\t" + item.IsIPv6LinkLocal);
                Console.WriteLine(item.ToString() + ":\t" + item.IsIPv6Multicast);
                Console.WriteLine(item.ToString() + ":\t" + item.IsIPv6SiteLocal);
                Console.WriteLine(item.ToString() + ":\t" + item.IsIPv6Teredo);

                if (item.AddressFamily == AddressFamily.InterNetwork)
                {
                    ip = item.ToString();
                }
            }
            return ip;
        }
        #endregion

        #region 获得本机名字
        public static string GetHostName()
        {
            return Dns.GetHostName();
        }
        #endregion

    }
}
